﻿/*
 * Creado por SharpDevelop.
 * Usuario: jfacorro
 * Fecha: 30/05/2010
 * Hora: 21:56
 * 
 * Para cambiar esta plantilla use Herramientas | Opciones | Codificación | Editar Encabezados Estándar
 */
using System;
using soundtouch;

namespace TimeMaker
{
	/// <summary>
	/// Description of BpmDetect.
	/// </summary>
	public class BpmDetection
	{
		/// <summary>
		/// Amount of samples that the buffer can contain
		/// </summary>
		private const int BUFF_SAMPLES_SIZE = 2048;

		unsafe public static float ExtractBPM(FMOD.Sound sound, FMOD.Channel channel)
		{
			int channels = 0;
			FMOD.SOUND_TYPE type = 0;
			FMOD.SOUND_FORMAT format = 0;
			int bits = 0;
			
			sound.getFormat(ref type, ref format, ref channels, ref bits);
			
			int numBytes = sizeof(float);
			
			uint bufferSizeInBytes = (uint)(BUFF_SAMPLES_SIZE * numBytes);

			float[] samples = new float[BUFF_SAMPLES_SIZE];
			byte * buffer = stackalloc byte[(int)bufferSizeInBytes];

			float freq = 0;
			channel.getFrequency(ref freq);
			BPMDetect bpm  = new BPMDetect(channels, (int)freq);
			
			bool done = false;

			uint read = 0;
			uint readTotal = 0;
			
			IntPtr ptr = new IntPtr(buffer);
			
			while(!done)
			{
				sound.readData(ptr, bufferSizeInBytes, ref read);

				for(uint i = 0; i < bufferSizeInBytes; i+= (uint)numBytes)
				{
					uint index = (uint)(i / numBytes);
					float sample = ((buffer[i + 3] & 0xFF) << 24) | ((buffer[i + 2] & 0xFF) << 16) | ((buffer[i + 1] & 0xFF) << 8) | (buffer[i] & 0xFF);
					samples[index] = sample;
				}

				// Verify that there are no more
				// bytes to be read and we're done
				done = read < bufferSizeInBytes;

				/// Get number of float samples
				uint numsamplesLR = read / sizeof(float);
				/// Take num channels into account
				uint numsamplesTotal = (uint)(numsamplesLR / channels);

				bpm.inputSamples(samples, numsamplesTotal);

				readTotal += read;
			}

			sound.seekData(0);

			return bpm.getBpm();
		}

	}
}
